//工具生成，请不要手动修改...
let BinaryReader: any, ObjDecoder: any
/** 需要传入kcoder模块来进行初始化 */
export function initXlsxVo(kcoder: { BinaryReader: any, ObjDecoder: any }) {
    BinaryReader = kcoder.BinaryReader
    ObjDecoder = kcoder.ObjDecoder
}

let dataDic: { [name: string]: Uint8Array } = {}
/** 读取表数据 */
export function loadData(bytes: Uint8Array) {
    let r = BinaryReader.alloc(bytes)
    while (r.hasNext) dataDic[r.str] = r.cut(r.uint)
}

function loadStruct(name: string) {
    let r = BinaryReader.alloc(dataDic[name])
    let struct = []
    //[读取] >>> uint字段数量
    let len = r.uint
    while (len--) {
        //[读取] >>> str字段 uint类型
        let str = r.str, vt = r.uint, st = [str, vt]
        if (vt > 18) {
            //[读取] >>> uint数组维度
            st.push(r.uint)
        }
        if ((vt > 10 && vt < 13) || (vt > 29) && (vt < 32)) {
            //[读取] >>> uint float特殊参数
            st.push(r.uint)
        }
        struct.push(st)
    }
    return { r, struct }
}

class Cfg<Vo> {
    constructor(private readonly name: string) { }
    /** 获取cfgvo*/
    get cfg(): Vo { this.load(); return this.cfg }
    private load() {
        let { r, struct } = loadStruct(this.name)
        let item = ObjDecoder.deStruct(r, struct)
        r.recy()
        Object.defineProperty(this, "cfg", { value: item })
    }
}

class Xlsx<Vo> {
    constructor(private readonly name: string) { }
    /** 通过id获取 */
    get(id: number | string): Vo { this.load(); return this.get(id) }
    /** 通过idx获取 */
    getAt(idx: number): Vo { this.load(); return this.getAt(idx) }
    /** 遍历所有item */
    count(): number { this.load(); return this.count() }
    /** item数量 */
    each(fn: (data: Vo, idx: number) => void) { this.load(); this.each(fn) }
    private load() {
        let { r, struct } = loadStruct(this.name)
        let items: any[] = [], id2Item: any = {}
        while (r.hasNext) {
            let item = ObjDecoder.deStruct(r, struct)
            items.push(id2Item[item["id"]] = item)
        }
        r.recy()
        let count = items.length
        this.get = id => id2Item[id]
        this.getAt = idx => items[idx]
        this.count = () => count;
        this.each = callback => items.forEach(callback)
    }
}

/** food.xlsx */
export const VFood = new Cfg<VFoodVo>("food")
export interface VFoodVo {
    /** 分数范围 */
    readonly score: number[]
    /** 超级食物分数范围 */
    readonly superFoodScore: number[]
    /** 超级食物生成几率范围 */
    readonly superFoodChance: number[]
    /** 战力品食物清除时间范围(s) */
    readonly clearTime: number[]
}

/** game.xlsx */
export const VGame = new Cfg<VGameVo>("game")
export interface VGameVo {
    /** 逻辑帧频 */
    readonly tps: number
}

/** snake.xlsx */
export const VSnake = new Cfg<VSnakeVo>("snake")
export interface VSnakeVo {
    /** 初始名称 */
    readonly initName: string
    /** 初始长度 */
    readonly initLen: number
    /** 初始宽度 */
    readonly initWidth: number
    /** 初始间隔 */
    readonly initSpacing: number
    /** 重生时间间隔(s) */
    readonly respawnTime: number
    /** 战利品基础分数范围 */
    readonly deathScore: number[]
    /** 进食范围 */
    readonly eatRange: number
    /** 冲刺最大倍数 */
    readonly sprintSpd: number
    /** 冲刺到最快速度所需时间(s) */
    readonly sprintSpdTime: number
    /** 冲刺每秒消耗分数 */
    readonly sprintCost: number
    /** 转弯保留宽度 */
    readonly turnWidth: number
    /** AI名称前缀 */
    readonly aiNamePre: string
}

/** world.xlsx */
export const VWorld = new Cfg<VWorldVo>("world")
export interface VWorldVo {
    /** 世界宽度 */
    readonly width: number
    /** 世界高度 */
    readonly height: number
    /** 区块大小 */
    readonly chunkSize: number
    /** 最大食物数量 */
    readonly foodMax: number
    /** 区块最大食物数量 */
    readonly chunkFoodMax: number
    /** 人机数量 */
    readonly aiCount: number
    /** 生成食物时间间隔(s) */
    readonly createFoodsTime: number
    /** 每次生成食物数量 */
    readonly createFoodCount: number
    /** 每条蛇增加的每次生成食物数量 */
    readonly createFoodCount2: number
    /** 清理战利品食物时间间隔(s) */
    readonly clearFoodsTime: number
}